package com.itheima.restkeeper.web;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.restkeeper.AffixFace;
import com.itheima.restkeeper.UserFace;
import com.itheima.restkeeper.basic.ResponseWrap;
import com.itheima.restkeeper.enums.UserEnum;
import com.itheima.restkeeper.exception.ProjectException;
import com.itheima.restkeeper.req.AffixVo;
import com.itheima.restkeeper.req.UserVo;
import com.itheima.restkeeper.utils.EmptyUtil;
import com.itheima.restkeeper.utils.ExceptionsUtil;
import com.itheima.restkeeper.utils.ResponseWrapBuild;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @ClassName UserController.java
 * @Description 用户Controller
 */
@RestController
@RequestMapping("user")
@Slf4j
@Api(tags = "用户controller")
public class UserController {

    @DubboReference(version = "${dubbo.application.version}",check = false)
    UserFace userFace;

    @DubboReference(version = "${dubbo.application.version}",check = false)
    AffixFace affixFace;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    /**
     * @Description 用户列表
     * @param userVo 查询条件
     * @return
     */
    @PostMapping("page/{pageNum}/{pageSize}")
    @ApiOperation(value = "查询用户分页",notes = "查询用户分页")
    @ApiImplicitParams({
       @ApiImplicitParam(name = "userVo",value = "用户查询对象",required = true,dataType = "UserVo"),
       @ApiImplicitParam(paramType = "path",name = "pageNum",value = "页码",dataType = "Integer"),
       @ApiImplicitParam(paramType = "path",name = "pageSize",value = "每页条数",dataType = "Integer")
    })
    public ResponseWrap<Page<UserVo>> findUserVoPage(
            @RequestBody UserVo userVo,
            @PathVariable("pageNum") int pageNum,
            @PathVariable("pageSize") int pageSize) throws ProjectException {
        try {
            //查询用户分页
            Page<UserVo> userVoPage = userFace.findUserVoPage(userVo, pageNum, pageSize);
            //用户不为空，则处理用户头像附件
            if (!EmptyUtil.isNullOrEmpty(userVoPage)) {
                userVoPage.getRecords().forEach(uVo->{
                    //用户头像可能存在多个，不知道如何选择，暂时选择第一个作为头像
                    if (!EmptyUtil.isNullOrEmpty(uVo)) {
                        AffixVo affixVo = affixFace.findAffixVoByBusinessId(uVo.getId()).get(0);
                        if (!EmptyUtil.isNullOrEmpty(affixVo)) {
                            uVo.setAffixVo(affixVo);
                        }
                    }
                });
            }
                //回填用户头像附件
            return ResponseWrapBuild.build(UserEnum.SUCCEED,userVoPage);
        } catch (Exception e) {
            log.error("查询用户列表异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.PAGE_FAIL);
        }
    }

    /**
     * @Description 注册用户
     * @param userVo 对象信息
     * @return
     */
    @PostMapping
    @ApiOperation(value = "注册用户",notes = "注册用户")
    @ApiImplicitParam(name = "userVo",value = "用户对象",required = true,dataType = "UserVo")
    ResponseWrap<UserVo> registerUser(@RequestBody UserVo userVo) throws ProjectException {
        try {
            //明文转密文密码，必须要加{bcrypt}要不认证不通过(照着抄)
            String password = "{bcrypt}"+bCryptPasswordEncoder.encode(userVo.getPassword());
            userVo.setPassword(password);
            //注册用户
            UserVo user = userFace.createUser(userVo);
            //绑定附件
            AffixVo affixVo = affixFace.bindBusinessId(AffixVo
                    .builder()
                    //绑定的附件id应该使用附件创建时产生的id
                    .id(userVo.getAffixVo().getId())
                    //绑定的业务id应该使用加入数据库
                    .businessId(user.getId())
                    .build());
            //回填用户头像附加
            user.setAffixVo(affixVo);
            //补全角色信息
            user.setHasRoleIds(userVo.getHasRoleIds());
            return ResponseWrapBuild.build(UserEnum.SUCCEED,user);
        } catch (Exception e) {
            log.error("保存用户异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.CREATE_FAIL);
        }
    }

    /**
     * @Description 修改用户
     * @param userVo 对象信息
     * @return
     */
    @PatchMapping
    @ApiOperation(value = "修改用户",notes = "修改用户")
    @ApiImplicitParam(name = "userVo",value = "用户对象",required = true,dataType = "UserVo")
    ResponseWrap<Boolean> updateUser(@RequestBody UserVo userVo) throws ProjectException {
        try {
            //修改用户信息
            Boolean aBoolean = userFace.updateUser(userVo);
            //修改成功，修改用户头像附加
            if (aBoolean) {
                //根据业务id删除所有的附件（我觉得逻辑存在问题，但我不会改）
                Boolean aBoolean1 = affixFace.deleteAffixVoByBusinessId(userVo.getId());
                affixFace.bindBusinessId(AffixVo
                        .builder()
                        //修改时会传所有的附件信息，所以这些信息全部从传入的参数拿取
                        .id(userVo.getAffixVo().getId())
                        .businessId(userVo.getId())
                        .build());
            }
            //返回结果
            return ResponseWrapBuild.build(UserEnum.SUCCEED,aBoolean);
        } catch (Exception e) {
            log.error("保存用户异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.UPDATE_FAIL);
        }
    }

    /**
     * @Description 删除用户
     * @param userVo 查询对象
     * @return
     */
    @DeleteMapping
    @ApiOperation(value = "删除用户",notes = "删除用户")
    @ApiImplicitParam(name = "userVo",value = "用户查询对象",required = true,dataType = "UserVo")
    ResponseWrap<Boolean> deleteUser(@RequestBody UserVo userVo ) throws ProjectException {
        try {
            //删除选择用户
            Boolean aBoolean = userFace.deleteUser(userVo.getCheckedIds());
            //删除图片
            Boolean aBoolean1 = affixFace.deleteAffixVoByBusinessId(userVo.getId());
            //返回结果
            return ResponseWrapBuild.build(UserEnum.SUCCEED,aBoolean&&aBoolean1);
        } catch (Exception e) {
            log.error("删除用户异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.DELETE_FAIL);
        }
    }

    /**
     * @Description 查找用户
     * @param userId 登录名
     * @return
     */
    @GetMapping("select-by-userId/{userId}")
    @ApiOperation(value = "查找用户",notes = "查找用户")
    @ApiImplicitParam(paramType = "path",name = "userId",value = "用户Id",example = "1",dataType = "Long")
    ResponseWrap<UserVo> findUserByUserId(@PathVariable("userId") Long userId) throws ProjectException {
        try {
            //查找用户信息
            UserVo userByUserId = userFace.findUserByUserId(userId);
            //返回结果
            return ResponseWrapBuild.build(UserEnum.SUCCEED,userByUserId);
        } catch (Exception e) {
            log.error("查找用户所有角色异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.SELECT_USER_FAIL);
        }
    }

    /**
     * @Description 查找用户list
     * @return
     */
    @GetMapping("select-list")
    @ApiOperation(value = "查找用户list",notes = "查找用户list")
    ResponseWrap<List<UserVo>> findUserVoList() throws ProjectException {
        try {
            //查询所有有效的用户信息
            List<UserVo> userVoList = userFace.findUserVoList();
            //返回结果
            return ResponseWrapBuild.build(UserEnum.SUCCEED,userVoList);
        } catch (Exception e) {
            log.error("查找用户list异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.SELECT_USER_LIST_FAIL);
        }
    }

    /**
     * 修改用户状态
     * @param userVo 用户vo
     * @return
     * @throws ProjectException
     */
    @PostMapping("update-user-enableFlag")
    @ApiOperation(value = "修改用户状态",notes = "修改用户状态")
    @ApiImplicitParam(name = "userVo",value = "用户查询对象",required = true,dataType = "UserVo")
    ResponseWrap<Boolean> updateUserEnableFlag(@RequestBody UserVo userVo) throws ProjectException {
        try {
            //修改用户状态
            Boolean aBoolean = userFace.updateUser(userVo);
            //返回结果
            return ResponseWrapBuild.build(UserEnum.SUCCEED,aBoolean);
        } catch (Exception e) {
            log.error("修改用户状态异常：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.UPDATE_FAIL);
        }
    }

    @PostMapping("rest-password")
    @ApiOperation(value = "重置用户密码",notes = "重置用户密码")
    @ApiImplicitParam(name = "userVo",value = "用户对象",required = true,dataType = "UserVo")
    ResponseWrap<Boolean> restPssword(@RequestBody UserVo userVo) throws ProjectException {
        //必须要加{bcrypt}要不认证不通过
        try {
            //修改用户密码
            Boolean aBoolean = userFace.updateUser(userVo);
            //返回结果
            return ResponseWrapBuild.build(UserEnum.SUCCEED,aBoolean);
        } catch (Exception e) {
            log.error("重置用户密码：{}", ExceptionsUtil.getStackTraceAsString(e));
            throw new ProjectException(UserEnum.UPDATE_FAIL);
        }
    }

}
